Single Inheritance

In single inheritance, any client class inherits from only one parent class. Lets look at the below example which contains Pen as parent and BallPen & InkPen as clildren of it.


In [6]:
class Pen():
    def __init__(self, size, name):
        self.name = name
        self.size = size
    
    def set_name(self, name):
        self.name = name


class BallPen(Pen):
    def __init__(self, size, name, color):
        self.color = color
        super().__init__(size, name)
    
    def set_color(self, color):
        self.color = color


class InkPen(Pen):
    def __init__(self, size, name, cart_type):
        self.cart = cart_type
        super().__init__(size, name)

BallPen & InkPen both are initializing the parent class using super().__init(size, name) function. Now lets create few objects of both,


In [9]:
pb = BallPen(10, "Renolds", "Green")
print(pb.name)
pb.set_name("cello")
print(pb.name)
print(pb.__dict__)


Renolds
cello
{'color': 'Green', 'name': 'cello', 'size': 10}

In [22]:
class grand_parent:
    def __init__(self, middle_name):
        print("grand_parent init")
        self.__middle_name = middle_name
        
    def middle_name(self, middle_name):
        self.__middle_name = middle_name
        return self.__middle_name

Lets create a parent class which inherits grand_parent class, note we have used super().__init_(middle_name) to set middle name using parents function middle_name.


In [23]:
class parent(grand_parent):
    def __init__(self, middle_name, surname):
        print("parent init")
        self.__surname = surname
        super().__init__(middle_name)
    
    def middle_name(self):
        return self.middle_name

Now lets create the student which inherits parent class. Check its init also.


In [24]:
class student(parent):
    def __init__(self, name, middle_name, surname):
        print("student init")
        self.name = name
        super().__init__(middle_name, surname)

In [26]:
mohan = student("Venkat", "kumar", "Mohan")


student init
parent init
grand_parent init

Check the order of init's being called.


In [16]:
print(mohan.middle_name)


<bound method parent.middle_name of <__main__.student object at 0x7f9df848b160>>

In [28]:
mohan.middle_name = "KUMAR"
print(mohan.middle_name)


KUMAR

Now lets create the same classes without init functions, and see what happens


In [44]:
class grand_parent:
    def __init__(self, middle_name):
        print("grand_parent init")
        self.__middle_name = middle_name
        
    def middle_name(self, middle_name):
        self.__middle_name = middle_name
        return self.__middle_name

class parent(grand_parent):
    def __init__(self, middle_name, surname):
        print("parent init")
        self.__surname = surname
    
    def middle_name(self):
        return self.__middle_name
    
    
class student(parent):
    def __init__(self, name, middle_name, surname):
        print("student init")
        self.name = name

In [45]:
mohan = student("Venkat", "kumar", "Mohan")


student init

In [48]:
try:
    print(mohan.middle_name())
except Exception as e:
    print(e)


'student' object has no attribute '_parent__middle_name'

We got the error because, init of none of the parent's were called, and only students init was called.


In [22]:
# NOTE: python 2 has issues with Super , get it also documented here